package cc.owoo.godpen.thread;

/**
 * 等待线程
 * Created by nimensei
 * 2020-05-29 下午 11:40
 **/
public abstract class WaitThread {
    private boolean threadLock;// 线程锁
    private int delay = 1000;// 延迟
    private long target = -1;// 目标时间点
    private boolean isExecute;// 是否还在执行
    private boolean isLock;// 是否上锁
    private boolean isStop;// 是否结束

    public WaitThread() {
    }

    public WaitThread(int delay) {
        this.delay = delay;
    }

    /**
     * 开始运行
     */
    public void execute(int delay) {
        this.delay = delay;
        execute();
    }

    public void execute() {
        if (isLock)
            return;
        target = System.currentTimeMillis() + delay;
        isExecute = true;
        isStop = false;
        if (threadLock)
            return;
        threadLock = true;
        new Thread() {
            public void run() {
                newThread();
                threadLock = false;
            }
        }.start();
    }

    /**
     * 锁
     */
    public boolean isLock() {
        return isLock;
    }

    public void setLock(boolean isLock) {
        this.isLock = isLock;
        if (isLock) {
            target = -1;
            isExecute = false;
        }
    }

    /**
     * 延迟
     * <p>
     * 调用start后，需要等待多少毫秒，线程才会运行
     */
    public int getDelay() {
        return delay;
    }

    public void setDelay(int delay) {
        this.delay = delay;
    }

    /**
     * 新的线程
     */
    private void newThread() {
        while (isExecute) {
            int delay = this.delay;
            while (true) {
                if (delay <= 0)
                    break;
                Threads.delay(delay);
                if (System.currentTimeMillis() >= target)
                    break;
                delay = (int) (target - System.currentTimeMillis());
            }
            if (isLock)
                return;
            if (isStop)
                return;
            run();
            isExecute = false;
        }
        isStop = true;
    }

    /**
     * 结束
     */
    public void stop() {
        isExecute = true;
        isStop = true;
    }

    public abstract void run();
}
